﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;

namespace UnitTesting.Fixturing
{
	class SimpleValueProvider : IValueProvider, ISimpleTypeStrategy, ISimpleTypeGenerator
	{
		public const int INCLUSIVE_MIN = 0;
		public const int EXCLUSIVE_MAX = 100;

		readonly CompositeSimpleValueProvider _compositeSimpleValueProvider;
		ISimpleTypeGenerator _simpleTypeGenerator;

		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		internal Type SimpleTypeGeneratorType
		{
			get { return _simpleTypeGenerator.GetType(); }
		}

		internal SimpleValueProvider()
		{
			_simpleTypeGenerator = new SimpleTypeRandom();
			_compositeSimpleValueProvider = new CompositeSimpleValueProvider(this);
		}

		public object Create(Type type)
		{
			Ensure.IsNotNull(() => type);
			return _compositeSimpleValueProvider.CreateSimpleValue(type);
		}

		public void WithSimpleTypeGenerator(ISimpleTypeGenerator simpleTypeGenerator)
		{
			Ensure.IsNotNull(() => simpleTypeGenerator);
			_simpleTypeGenerator = simpleTypeGenerator;
		}

		public int Next(Type simpleType)
		{
			return _simpleTypeGenerator.Next(simpleType);
		}

		internal static void EnsureIsValidRange(int inclusiveMin, int exclusiveMax)
		{
			if (inclusiveMin == exclusiveMax)
			{
				throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The inclusive min '{0}' and exclusive max '{1}' cannot be same.", inclusiveMin, exclusiveMax));
			}
			if (inclusiveMin > exclusiveMax)
			{
				throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The inclusive min '{0}' cannot be great than the exclusive max '{1}'.", inclusiveMin, exclusiveMax));
			}
		}
	}
}